/**
 * (created at 2011-1-14)
 */
package qiushuo.mysqlparser.recognizer.parser;

import java.sql.SQLSyntaxErrorException;

import qiushuo.mysqlparser.recognizer.SQLToken;
import qiushuo.mysqlparser.recognizer.SQLTokenType;
import qiushuo.mysqlparser.recognizer.TokenReader;

/**
 * @author <a href="mailto:QiuShuo1985@gmail.com">QIU Shuo</a>
 */
public abstract class Parser {
    protected TokenReader input;

    /**
     * state of field {@link #input} should never be changed during construction
     */
    public Parser(TokenReader input) {
        this.input = input;
    }

    /**
     * @throws SQLSyntaxErrorException unmatch
     */
    protected SQLToken match(SQLTokenType type) throws SQLSyntaxErrorException {
        SQLToken token = input.next();
        if (token == null) {
            err("expecting type " + type + " but is null");
        }
        if (!token.isTypeOf(type)) {
            err("expecting type " + type + " but is " + token.getType());
        }
        return token;
    }

    /**
     * @param expectText uppercase if ignoreCaswe is true
     * @throws SQLSyntaxErrorException unmatch
     */
    protected SQLToken match(SQLTokenType type, boolean ignoreCaswe, String expectText) throws SQLSyntaxErrorException {
        SQLToken token = input.next();
        if (token == null) {
            err("expecting type " + type + " but is null");
        }
        if (!token.isTypeOf(type)) {
            err("expecting type " + type + " but is " + token.getType());
        }
        String text = token.getText();
        if (text == null) {
            if (expectText != null) {
                err("expecting null text but is " + token.getText());
            } else {
                return token;
            }
        }
        if (ignoreCaswe) {
            if (!expectText.equals(text.toUpperCase())) {
                err("expecting text of '" + expectText + "' but is " + token.getText());
            }
        } else {
            if (!expectText.equals(token.getText())) {
                err("expecting text of '" + expectText + "' but is " + token.getText());
            }
        }
        return token;
    }

    /**
     * side-effect is forbidden: it is possible for this method to be normal
     * branch, see {@link DMLParser#tableRefs()}
     */
    protected SQLSyntaxErrorException err(String msg) throws SQLSyntaxErrorException {
        StringBuilder errmsg = new StringBuilder();
        errmsg.append(msg).append(". ").append(input.toString());
        throw new SQLSyntaxErrorException(errmsg.toString());
    }
}
